using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SAInterfaceLibrary;
using Microsoft.Win32;
using System.Diagnostics;
using System.IO;

namespace ROOTBuildProjectCreatorSA
{
    public partial class BuildProjectOptions : Form
    {
        Properties.Settings _settings = new ROOTBuildProjectCreatorSA.Properties.Settings();
        public BuildProjectOptions()
        {
            EventLogger.LoadMinLevelFromInt(_settings.LogLevel);
            InitializeComponent();
        }

        /// <summary>
        /// Init with some default arguments...
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            if (!DesignMode)
            {
                try
                {
                    tbROOTSYS.KeyUp += new KeyEventHandler(tbROOTSYS_KeyUp);

                    ///
                    /// Parallel builds? Depends on how many CPUs there are for a guess...
                    /// 

                    tbNumberOfParallelBuilds.Text = Environment.ProcessorCount.ToString();

                    ///
                    /// Load in the default spec
                    /// 

                    bsConfig.BuildSpec = ProjectBuildConfigSpec.LoadDefaultConfig();

                    ///
                    /// Next, do the versions
                    /// 

                    string default_version = Configuraiton.Instance.DefaultMSVCVersion;
                    int default_version_index = -1;
                    int count = 0;
                    foreach (string version_name in Configuraiton.Instance.MSVCVersionsSupported)
                    {
                        cbMSVCVersion.Items.Add(version_name);
                        if (version_name == default_version)
                        {
                            default_version_index = count;
                        }
                        count = count + 1;
                    }
                    cbMSVCVersion.SelectedIndex = default_version_index;
                }
                catch (Exception info)
                {
                    EventLogger.LogException("Error setting up window defaults", info, EventLogEntryType.Error, 100);
                    throw;
                }
            }
        }

        /// <summary>
        /// Window is closing. Clean up and write everything out.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);

            Properties.Settings.Default.Save();
        }

        /// <summary>
        /// Look for a return to similate generateing the ide.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void tbROOTSYS_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Return)
            {
                button1.Focus();
                GenerateIDEFiles();
            }
        }

        /// <summary>
        /// User would like to find the place where the ROOT files are located.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bBrowseForROOTSYS_Click(object sender, EventArgs e)
        {
            if (tbROOTSYS.Text != "")
            {
                fbFindFolder.SelectedPath = tbROOTSYS.Text;
            }
            if (fbFindFolder.ShowDialog() == DialogResult.OK)
            {
                tbROOTSYS.Text = fbFindFolder.SelectedPath;
            }
        }

        /// <summary>
        /// Everything is set -- lets try to generate the project now.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            ///
            /// Make sure the ROOTSYS isn't empty!
            /// 

            if (tbROOTSYS.Text.Length == 0)
            {
                MessageBox.Show("You must enter a path for ROOTSYS");
                return;
            }

            if (!Directory.Exists(tbROOTSYS.Text))
            {
                MessageBox.Show("The path you entered for ROOTSYS must exist!");
                return;
            }

            if (tbROOTSYS.Text.Contains(" "))
            {
                if (MessageBox.Show("ROOTSYS contains a <space> character - normally ROOT doesn't build in this case.", "ROOTSYS Contains Space", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
                    return;
            }

            ///
            /// Generate the various files
            ///

            GenerateIDEFiles();
        }

        private void GenerateIDEFiles()
        {
            try
            {
                ///
                /// TODO: Add validation
                /// 

                ///
                /// Tell the rest of the system what version we are going to be
                /// generating for!
                /// 

                Configuraiton.Instance.SetMSVCVersion(cbMSVCVersion.Text);

                ///
                /// Specify how we want to do this
                /// 

                ProjectCreationInfo ci = new ProjectCreationInfo();
                ci.ROOTSYSDirectory = tbROOTSYS.Text;

                ///
                /// Number of parallel builds. Turn off feature if single threaded build.
                ///

                ci.NumberOfParallelMakeJobs = Convert.ToInt32(tbNumberOfParallelBuilds.Text);
                if (ci.NumberOfParallelMakeJobs <= 1)
                {
                    ci.NumberOfParallelMakeJobs = 0;
                }

                ///
                /// Load up the project specifications from the UI
                /// 

                ci.ClearProjectBuildConfigs();
                ci.AddProjectBuildConfig(bsConfig.BuildSpec);

                ///
                /// Now, create the thing!
                /// 

                Cursor = Cursors.WaitCursor;
                try
                {

                    ProjectCreator pc = new ProjectCreator(ci);
                    FileInfo fi = pc.Create();
                    if (cbStartDevEnv.Checked)
                    {
                        StartDevenv(fi);
                    }
                    if (cbCloseWindowWhenDone.Checked)
                    {
                        Close();
                    }
                }
                finally
                {
                    Cursor = Cursors.Default;
                }
            }
            catch (Exception e)
            {
                EventLogger.LogException("Error trying to generate IDE files", e, EventLogEntryType.Error, 101);
                throw;
            }
        }

        /// <summary>
        /// Try to find the devenv and start it.
        /// </summary>
        private void StartDevenv(FileInfo fi)
        {
            try
            {
                string install_dir = Configuraiton.Instance.IDEInstallDir + @"\devenv.exe";
                ProcessStartInfo si = new ProcessStartInfo(install_dir, fi.FullName);
                Process.Start(si);
            }
            catch
            {
                MessageBox.Show("Unable to find MSVC's install directory; you'll have to start it on your own");
                return;
            }
        }

        /// <summary>
        /// The field has changed? If so, then w eshould try to re-read the options if they
        /// exist.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tbROOTSYS_Leave(object sender, EventArgs e)
        {
            if (_cached_rootsys_value != tbROOTSYS.Text)
            {
                ExistingProjectInfo info = new ExistingProjectInfo(tbROOTSYS.Text);
                ProjectBuildConfigSpec spec = info.GetSpec();
                if (spec != null)
                {
                    bsConfig.BuildSpec = spec;
                }
            }
        }

        private string _cached_rootsys_value;

        /// <summary>
        /// Remember the value before it is changed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tbROOTSYS_Enter(object sender, EventArgs e)
        {
            _cached_rootsys_value = tbROOTSYS.Text;
        }

        /// <summary>
        /// User wants to load up a new template... Hate dialog boxes, but without a wizzard, this seems like the
        /// simplest thing to do.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void bLoadConfigTemplate_Click(object sender, EventArgs e)
        {
            LoadConfigTemplateDialog dlg = new LoadConfigTemplateDialog();
            dlg.TemplateName = bsConfig.BuildSpec.Name;
            if (dlg.ShowDialog(this) == DialogResult.OK)
            {
                if (dlg.TemplateName.Length > 0)
                {
                    bsConfig.BuildSpec = ProjectBuildConfigSpec.LoadConfig(dlg.TemplateName);
                }
            }
        }
    }
}